home *** CD-ROM | disk | FTP | other *** search
- ;void prt_center(strg,field_size,fill_char,printer_codes)
- ; char *strg,fill_char,*printer_codes;
- ; int field_size;
-
- EXTRN _memory_model:byte
- EXTRN _error_code:byte
- EXTRN _time_out:byte
-
- _TEXT SEGMENT BYTE PUBLIC 'CODE'
- ASSUME CS:_TEXT
- PUBLIC _prt_center
- _prt_center proc near
- push bp ;
- mov bp,sp ;
- push di ;
- push si ;
- push ds ;
- cmp _memory_model,0 ;near or far?
- jle begin ;jump if near
- inc bp ;else add 2 to BP
- inc bp ;
- begin: jmp short A1
- keep_count dw ?
- keep_target dw ?
- strg_len db ?
- right_border dw ?
- field_size db ?
- fill_char db ?
- codes_seg dw ?
- codes_ofs dw ?
- A1: mov ah,1 ;BIOS func to init prtr
- sub dx,dx ;choose LPT1
- int 17h ;initialize the prtr port
- sub ax,ax ;clear AX
- mov es,ax ;point ES to 0000:0000
- mov dx,es:[408h] ;get LPT1 base address
- mov _error_code,1 ;1 = printer error
- mov al,_time_out ;get _time_out seconds
- cmp _memory_model,2 ;data near or far?
- jb B1 ;jump if near
- lds si,dword ptr[bp+4] ;DS:SI pts to Strg
- mov bh,[bp+8] ;field size
- mov bl,[bp+10] ;fill char
- les di,dword ptr[bp+12] ;ES:DI pts to PrinterCodes
- jmp short B2 ;
- B1: mov si,[bp+4] ;NEAR case
- mov bh,[bp+6] ;
- mov bl,[bp+8] ;
- mov di,[bp+10] ;
- push ds ;
- pop es ;
- B2: mov cs:field_size,bh ;store parameters for later
- mov cs:fill_char,bl ;
- mov cs:codes_seg,es ;
- mov cs:codes_ofs,di ;
- or al,al ;don't allow 0 seconds in time out
- jnz C1 ;
- mov al,3 ;default to 3 seconds
- C1: mov cl,18 ;18 ticks per second
- mul cl ;
- mov cs:keep_count,ax ;save count
- sub cx,cx ;clear CX
- mov cs:strg_len,0 ;in case null string
- cmp byte ptr[si],0 ;test for null input string
- je F1 ;
- push si ;go count number code chars in Strg
- sub cx,cx ;also count string length
- sub al,al ;AL counts control codes
- D1: mov ah,[si] ;get char from Strg
- or ah,ah ;terminating null yet?
- jz E2 ;quit loop if so
- cmp ah,128 ;test lower end of range
- jb E1 ;jump if below
- cmp ah,159 ;test upper limit
- ja E1 ;jump if above
- inc al ;else inc code counter
- E1: inc si ;forward string pointer
- inc cx ;inc string length counter
- jmp short D1 ;go check next char
- E2: pop si ;
- mov cs:strg_len,cl ;save string length
- sub ah,ah ;clear AH
- sub cx,ax ;num printed chrs in Strg
- F1: sub ax,ax ;clear AX
- mov al,cs:field_size ;line length (255 max)
- or al,al ;test for zero
- jz M1 ;quit if zero
- cmp cx,ax ;compare Strg, field lens
- jbe G1 ;jump if Strg <=
- mov cx,ax ;print only part of Strg
- mov cs:strg_len,cl ;
- sub ax,ax ;use 0 in calculation
- jmp short H1 ;jump below
- G1: sub ax,cx ;minus string length
- H1: mov cx,ax ;copy in CX
- shr ax,1 ;div by 2
- sub cx,ax ;remainder
- mov cs:right_border,cx ;save right border length
- mov cx,ax ;left border
- jcxz J1 ;jump if no left border
- I1: mov al,cs:fill_char ;fetch fill character
- call Writeit ;print a char
- or ah,ah ;check for printer error
- jz M1 ;quit if error
- loop I1 ;go do next on left
- J1: mov cl,cs:strg_len ;
- mov ch,cs:fill_char ;copy fill char in CH
- or cl,cl ;test for null string
- jz R1 ;jump ahead if null
- K1: mov al,[si] ;get a character
- cmp al,128 ;test if control code
- jb P1 ;jump if below range
- cmp al,159 ;test if above
- ja P1 ;jump if above
- push cx ;save Strg len ctr
- push si ;save Strg pos ptr
- push ax ;point ES:DI to PrinterCodes
- mov ax,cs:codes_seg
- mov es,ax
- mov di,cs:codes_ofs
- pop ax
- sub al,128 ;count codes from 0
- mov cl,6 ;times six bytes
- mul cl ;offset in PrinterCodes
- add di,ax ;SI pts to code sequence
- sub cx,cx ;clear CX
- mov cl,es:[di] ;get string descriptor
- jcxz O1 ;quit loop if null
- L1: inc di ;forward ptr
- mov al,[di] ;get code character
- call Writeit ;
- or ah,ah ;printer error?
- jnz N1 ;continue if not
- pop si ;restore Strg pos ptr
- pop cx ;restore Strg len ctr
- M1: jmp short U1 ;go quit routine
- N1: loop L1 ;go do next
- O1: pop si ;restore Strg pos ptr
- pop cx ;restore Strg len ctr
- jmp short Q1 ;go get next char in Strg
- P1: call Writeit ;
- or ah,ah ;proc returned error?
- jz U1 ;quit if so
- Q1: inc si ;forward Strg ptr
- dec cl ;dec Strg len ctr
- jnz K1 ;loop till finished
- R1: mov al,ch ;fill char to AL
- mov cx,cs:right_border ;right border length
- jcxz T1 ;quit if no right border
- mov ch,al ;copy back to CH
- S1: mov al,ch ;fill char to AL
- call Writeit ;
- or ah,ah ;check for printer error
- jz U1 ;quit if error
- dec cl ;dec border len counter
- jnz S1 ;loop till finished
- T1: pop ds ;
- dec _error_code ;0 = no error
- jmp short V1 ;
- U1: pop ds ;
- V1: pop si ;
- pop di ;
- pop bp ;
- cmp _memory_model,0 ;quit
- jle quit ;
- db 0CBh ;RET far
- quit: ret ;RET near
- Writeit PROC
- out dx,al ;send to output data register
- inc dx ;forward to status register
- push cx ;save string counter
- call GetBiosCount ;get timer reading
- mov bx,cx ;make copy
- add cx,cs:keep_count ;add delay count
- cmp bx,cx ;if timer doesn't turn over...
- jb W1 ;go ahead
- mov cx,cs:keep_count ;otherwise, extend delay
- W1: mov cs:keep_target,cx ;save target count on stack
- Wait: in al,dx ;get status value
- test al,8 ;test for printer error
- jz Error ;
- test al,80h ;test for Printer Ready
- jnz Ready ;jump if ready
- Error: call GetBiosCount ;
- cmp cx,cs:keep_target ;compare to target
- jb Wait ;
- mov bl,1 ;1 = error
- pop cx ;restore string counter
- mov ah,0 ;return code for failure
- jmp short X1 ;return
- Ready: pop cx ;restore string counter
- inc dx ; output control register
- mov al,13 ;bits for strobe signal
- out dx,al ;send the signal
- dec al ;change to strobe OFF
- out dx,al ;send the signal
- dec dx ;point back to
- dec dx ; base address
- mov ah,1 ;return code for success
- X1: ret ;
- Writeit endp
- GetBIOSCount PROC
- push dx ;return value in CX:DX
- push ax ;
- sub ah,ah ;function number
- int 1ah ;get timer count
- mov cx,dx ;low word in CX
- pop ax ;
- pop dx
- ret
- GetBIOSCount endp
- _prt_center endp
- _TEXT ENDS
- END